package com.hzqy.service.epg;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hzqy.commons.service.AuthenticatedService;
import com.hzqy.persistence.dao.epg.AcPopUpsDao;
import com.hzqy.persistence.dao.epg.AcUserBillDao;
import com.hzqy.web.vo.AuthenticatedVo;
import com.hzqy.web.vo.epg.AcPopUpsVo;
import com.hzqy.web.vo.epg.AcProductsVo;
import com.hzqy.web.vo.epg.AcUserBillVo;

import com.hzqy.web.vo.epg.ActivityProductVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Service
public class AcUserBillServiceBean {
	protected final Logger LOG = LoggerFactory.getLogger(getClass());

	/**超级少儿服务ID*/
	private final static String kidService = "00000001000000110000000000000406";

	/**超清影院服务ID*/
	private final static String[] vipService = {"ctcpack0000000000000000000001983"};

	/**电影VIP，环球影院服务ID*/
	private final static String[] movService = {"00000001000000110000000000000441", "00000001000000110000000000000404"};

	/**电视剧VIP，环球剧场服务ID*/
	private final static String[] tvService = {"00000001000000110000000000000443","00000001000000110000000000000390"};

	/**电视剧vip 2.环球剧场包月产品ID*/
	private final static String[] tvProduct = {"100096","90311418"};

	/**电影vip 2.环球影院包月产品ID*/
	private final static String[] mvProduct = {"100095","90312853"};

	@Resource
	private AcUserBillDao acUserBillDao;
	@Resource
	private AcPopUpsDao acPopUpsDao;
	@Resource
	private AcProductService acProductService;

	public void printlnOut(HttpServletResponse resp, String callback,Map<String,String> map) {
		PrintWriter out = null;
		try {
			resp.setContentType("text/plain");
			resp.setHeader("Access-Control-Allow-Origin","*");
			resp.setHeader("Pragma", "No-cache");
			resp.setHeader("Cache-Control", "no-cache");
			resp.setDateHeader("Expires", 0);
			resp.setCharacterEncoding("utf-8");
			String result;
			if(callback == null || "".equals(callback)) {
				result = JSON.toJSONString(map);
			}else {
				result = callback + "(" + JSON.toJSONString(map) + ")";
			}
			out = resp.getWriter();
			out.println(result);
		} catch (Exception e) {
			LOG.error("marketing_ERROR :", e);
		} finally{
			if(out != null){
				out.flush();
				out.close();
			}
		}
	}

	public Map<String,String> requestUserResultMap(HttpServletRequest request,HttpServletResponse response,String userID, int activityId, String type) {
		try{
			/*
			 * if(!"kid".equals(type) && !"mv".equals(type)){ return
			 * getMapResult("0","6","请传入正确的活动类型mv或kid！"); }
			 */
			String messageName = type;
			/*
			 * if("mv".equals(type)){ messageName = "影视剧"; }
			 */
			String today_Key = type+userID;
			String today = RedisService.getStringData(today_Key);
			LOG.debug(today);
			if(null==today) {//判断当天用户是否已调用该接口
				RedisService.setUserLoginUnixOneDay(today_Key);
				ActivityProductVo apv = acProductService.selectAcProdectByID(activityId);
				Date starttime = datesubstr(apv.getF_ap_startdate());
				Date acEndtime = datesubstr(apv.getF_ap_enddate());
				Date dateStr = new Date();
				if(starttime != null && acEndtime != null && !dateStr.before(acEndtime) && dateStr.after(starttime)){//不在活动时间内 return
					return getMapResult("0","0","不在活动时间内！");
				}else{
					AcUserBillVo aub;
					AcUserBillVo aubv = new AcUserBillVo();
					aubv.setF_aub_serverid(userID);
					aubv.setF_aub_productid(activityId);
					int flag = acUserBillDao.selectByServiceId(userID,activityId);//查用户是否在活动表中
					String productAuthStr = productAuth(request, response, userID, type);
					if("600".equals(productAuthStr)) {
						return getMapResult("0","60","请检查活动类型！");
					}else if("0".equals(productAuthStr)) {//鉴权 -- 1:未订购去表中查是否在活动表中 2:订购去匹配配置表中的产品包
						if(flag>0) {//已存在且已订购 不可参与
							aub = acUserBillDao.selectUserBill(aubv);
							Date orderEndTime = getUserOrderEndDate(aub.getF_aub_endtime());//订购结束时间
							if(acEndtime != null && !"4".equals(String.valueOf(aub.getF_aub_type())) && dateStr.before(acEndtime) && dateStr.after(orderEndTime)) {
								acUserBillDao.updateAcUserBill(userID,activityId,"4");//改成已订购用户
							}
							return getMapResult("0","10","已订购"+messageName+"，不弹窗！");
						}else{//不存在已订购 ，查询用户是否将来有资格参与，有则插入同步用户
							if("xm".equals(type)) {//戏曲订购为进行同步，
								return getMapResult("0","25","戏曲订购用户，不同步！");
							}else {//已订购，不在活动用户列表 ，查询用户已订购的产品包是否在活动所面向的产品包里，有则将来有资格参与，则插入同步用户//若不使用
								return queryUserOrderInsert(request,response,apv,userID,activityId);
							}
						}
					}else{//未订购
						if(flag<1) {
							return getMapResult("0","11",messageName+"用户未订购，非活动面向用户！");
						}else {//活动面向用户  未订购
							aub = acUserBillDao.selectUserBill(aubv);
                            if("504".equals(productAuthStr) && !"3".equals(String.valueOf(aub.getF_aub_type()))){//修改为未订购状态
								acUserBillDao.updateAcUserBill(userID,activityId,"3");
							}else if("100".equals(productAuthStr) && !"5".equals(String.valueOf(aub.getF_aub_type()))){//修改为已订购电影
                                acUserBillDao.updateAcUserBill(userID,activityId,"5");
                            }else if("200".equals(productAuthStr) && !"6".equals(String.valueOf(aub.getF_aub_type()))){//修改为已订购电视剧
                                acUserBillDao.updateAcUserBill(userID,activityId,"6");
                            }
							String activityNum_KEY = "num"+type+userID;//用于记录当月参与数.key:acNum+type+userID
							List<String> numList = RedisService.getListData(activityNum_KEY);
							int allNum = apv.getF_ap_frequency();
							if(allNum<=numList.size()) {
								return getMapResult("0","3","当月全部活动已参与！");
							}else {//订购到期后几天弹窗
								Date orderStartTime = getUserAlertDate(aub.getF_aub_endtime(),apv.getF_ap_heaven());
								if(acEndtime != null && dateStr.before(acEndtime) && dateStr.after(orderStartTime)) {
									//存入月记录
									RedisService.setPopUtsUnixOneMonth(activityNum_KEY);
									//活动用户每日插入弹窗时间数据
									AcPopUpsVo apuv = new AcPopUpsVo();
									apuv.setF_apul_serverid(userID);
									apuv.setF_apul_activityid(activityId);
									acPopUpsDao.insertPopUps(apuv);
									return getMapResult("1","2",messageName+"弹窗！",aub);
								}else {
									return getMapResult("0","12",messageName+"用户可参与活动，但是到期后弹窗时间没到！");
								}
							}
						}
					}
				}
			}else{
				return getMapResult("0","7","当天已调用过该接口！");
			}
		}catch (Exception e){
			//LOG.error("后台异常：用户："+userID+e+"||"+e.getMessage());
			return getMapResult("0","1","catch异常错误！");
		}
	}

	/**
	 * 查询用户订购信息并插入符合活动订购数据
	 */
	private Map<String, String> queryUserOrderInsert(HttpServletRequest request,HttpServletResponse response, ActivityProductVo apv, String userID, int activityId)throws ParseException {
		Map<String ,String> productResult;
		boolean breakFlag = false;
		List<String> product = new ArrayList<>();//记录可参与活动用户产品包
		List<String> orderStart = new ArrayList<>();//记录可参与活动用户订购开始时间
		List<String> orderEnd = new ArrayList<>();//记录可参与活动用户订购结束时间
		List<String> productName = new ArrayList<>();//记录可参与活动用户订购结束时间
		productResult = getProductsOrdered(userID,request,response);
		String result = productResult.get("result");
		int size = Integer.parseInt(productResult.get("size"));
		String[] products = new String[size];
		String[] orderStarts = new String[size];
		String[] orderEnds = new String[size];
		String[] productnames = new String[size];
		if(!"-1".equals(result)) {
			//取出订购产品 比对
			for(int i=0;i<size;i++) {
				products[i] = productResult.get("product_"+i);
				orderStarts[i] = productResult.get("startTime_"+i);
				orderEnds[i] = productResult.get("endTime_"+i);
				productnames[i] = productResult.get("productname_"+i);
			}
			String[] acProducts = splits(apv.getF_ap_productcode());
			LOG.debug("acProducts 活动配置产品包个数："+acProducts.length);
			for(int j=0;j<size;j++) {
				for(String s : acProducts) {
					if(products[j].equals(s)) {
						product.add(products[j]);
						orderStart.add(orderStarts[j]);
						orderEnd.add(orderEnds[j]);
						productName.add(productnames[j]);
						breakFlag = true;
						break;
					}
				}
			}

			if(breakFlag) {//后期有资格用户记录
				//insert userBill -- 修改状态 2
				SimpleDateFormat ymdhms = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				Date d = new Date();
				for(int i=0;i<product.size();i++) {
					AcUserBillVo insertVo = new AcUserBillVo();
					insertVo.setF_aub_serverid(userID);
					insertVo.setF_aub_productcode(Integer.valueOf(product.get(i)));
					insertVo.setF_aub_productname(String.valueOf(productName.get(i)));
					insertVo.setF_aub_productid(activityId);
					insertVo.setF_aub_type(2);
					insertVo.setF_aub_ordertime(ymdhms.parse(dateChange(orderStart.get(i))));
					insertVo.setF_aub_endtime(ymdhms.parse(dateChange(orderEnd.get(i))));
					insertVo.setF_aub_cdate(ymdhms.format(d));
					acUserBillDao.insertUserBill(insertVo);
				}
				return getMapResult("0","20","同步接口插入活动用户数据！");
			}else {
				return getMapResult("0","21","同步接口未查询到匹配数据，不插入数据！");
			}
		}else {
			return getMapResult("0","22","同步接口订购产品查询失败！");
		}
	}

	private Date getUserAlertDate(Date dateStr,int endDay) throws ParseException{
		SimpleDateFormat ymdhms = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		SimpleDateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");
		Calendar ca = Calendar.getInstance();

		Date orderEndTime = ymd.parse(ymdhms.format(dateStr));//订购结束时间
		ca.setTime(orderEndTime);
		ca.add(Calendar.DATE, endDay);
		return ymdhms.parse(ymdhms.format(ca.getTime()));//到期用户活动开始时间
	}

	private Date getUserOrderEndDate(Date dateStr) throws ParseException{
		SimpleDateFormat ymdhms = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		SimpleDateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");
		return ymd.parse(ymdhms.format(dateStr));
	}

	private Map<String ,String> getMapResult(String result, String msg, String message){
		Map<String ,String> map = new HashMap<>();
		map.put("result", result);
		map.put("msg", msg);//异常
		LOG.debug("map:"+map.toString()+"|提示信息："+message);
		return map;
	}
	private Map<String ,String> getMapResult(String result, String msg, String message,AcUserBillVo aubv){
		Map<String ,String> map = new HashMap<>();
		map.put("result", result);
		map.put("msg", msg);//异常
		map.put("productname",aubv.getF_aub_productname());
		SimpleDateFormat ymdhms = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		map.put("endtime", ymdhms.format(aubv.getF_aub_endtime()));
		LOG.debug("map:"+map.toString()+"|提示信息："+message);
		return map;
	}

	/**
	 *  用户订购列表查询
	 *	return map()
	 *	key:result
	 *	value : "504"未订购
	 *	value : "-1"请求异常
	 *   value : "0"已订购 --- > key : size 已订购产品包数量     key :  product_ '+' i 已订购产品包id
	 * @param userid 用户机顶盒账号
	 * @return 返回用户订购信息
	 */
	private Map<String,String> getProductsOrdered(String userid ,HttpServletRequest request,HttpServletResponse response) {
		Map<String,String> map = new HashMap<>();
		AuthenticatedService authenticatedService = new AuthenticatedService(request,response);
		String result = authenticatedService.getProductsOrdered(userid);
		JSONObject obj = JSONObject.parseObject(result);
		LOG.debug("json.result = "+obj.get("result").toString());
		if("504".equals(obj.get("result").toString())) {
			map.put("result", "504");
		}else if("-1".equals(obj.get("result").toString())){
			map.put("result", "-1");
		}else {
			LOG.debug(obj.get("products").toString());
			List<AcProductsVo> acpv= JSONObject.parseArray(obj.get("products").toString(),AcProductsVo.class);
			String size = String.valueOf(acpv.size());
			for(int i=0;i<acpv.size();i++) {
				String product = acpv.get(i).getProductId();
				String startTime = acpv.get(i).getStartTime();
				String endTime = acpv.get(i).getEndTime();
				String productname = acpv.get(i).getProductName();

				map.put("product_"+i, product);
				map.put("startTime_"+i, startTime);
				map.put("endTime_"+i, endTime);
				map.put("productname_"+i, productname);
			}
			map.put("result", "0");
			map.put("size", size);
			LOG.debug("订购详情--产品包+订购开始，结束时间："+map.toString());
		}
		return map;
	}

	/**
	 * 超级少儿，电影电视剧鉴权
	 * @return 已订购第三方产品返回0，未订购或已订购
	 */
	private String productAuth(HttpServletRequest request, HttpServletResponse response, 
			String userID, String type){
		epgCommonService epgCommonService = new epgCommonService();
		Map<String,Object> map = epgCommonService.getOrderType(userID,request,response);
		if("xm".equals(type)) {
			if("0".equals(String.valueOf(map.get("xm_month"))) ) {
				return "0";
			}else {
				return "504";
			}
		}else if("kid".equals(type)){
			try {
				return serviceAuth( userID, kidService, request, response);
			}catch(Exception e) {
				//LOG.error("超级少儿鉴权异常 用户："+userID+","+e.getMessage());
				return "504";
			}
			/*
			 * if("0".equals(String.valueOf(map.get("kid_month"))) ||
			 * "0".equals(String.valueOf(map.get("kid_ThirdLine")))) { return "0"; }else {
			 * return "504"; }
			 */
		}else if("mtv".equals(type)) {
			String mvResult = "504";
			String tvResult = "504";
			if("0".equals(String.valueOf(map.get("mtv_month"))) || "0".equals(String.valueOf(map.get("mtv_ThirdLine")))) {
				LOG.debug("鉴权结果订购影视剧 用户：" + userID);
				return "0";
			}else {
				if("0".equals(String.valueOf(map.get("mv_month"))) || "0".equals(String.valueOf(map.get("mv_ThirdLine")))) {
					mvResult = "0";
				}
				if("0".equals(String.valueOf(map.get("tv_month"))) || "0".equals(String.valueOf(map.get("tv_ThirdLine")))) {
					tvResult = "0";
				}
			}
			if ("0".equals(mvResult) && "504".equals(tvResult)) {
				LOG.debug("鉴权结果未订购电视剧包但是订购电影包月 用户：" + userID);
				return "100";
			}else if ("504".equals(mvResult) && "0".equals(tvResult)) {
				LOG.debug("鉴权结果未订购电影包但是订购电视剧包月 用户：" + userID);
				return "200";
			}else if ("504".equals(mvResult) && "504".equals(tvResult)) {
				LOG.debug("鉴权结果未订购电视剧包且未订购电影包 用户："+userID);
				return "504";
			}else if ("0".equals(mvResult) && "0".equals(tvResult)) {
				LOG.debug("鉴权结果已订购影视剧或者电视剧包和电影包 用户："+userID);
				return "0";
			}
		}else if("mv".equals(type)){//电影
			if("0".equals(String.valueOf(map.get("mtv_month"))) || "0".equals(String.valueOf(map.get("mtv_ThirdLine")))) {
				LOG.debug("鉴权结果订购影视剧 用户：" + userID);
				return "0";
			}else {
				if("0".equals(String.valueOf(map.get("mv_month"))) || "0".equals(String.valueOf(map.get("mv_ThirdLine")))) {
					return "0";
				}else {
					return "504";
				}
			}
		}else if("tv".equals(type)){//电视剧
			if("0".equals(String.valueOf(map.get("mtv_month"))) || "0".equals(String.valueOf(map.get("mtv_ThirdLine")))) {
				LOG.debug("鉴权结果订购影视剧 用户：" + userID);
				return "0";
			}else {
				if("0".equals(String.valueOf(map.get("tv_month"))) || "0".equals(String.valueOf(map.get("tv_ThirdLine")))) {
					return "0";
				}else {
					return "504";
				}
			}
		}
		/*
		if("kid".equals(type)){
			try {
				return serviceAuth( userID, kidService, request, response);
			}catch(Exception e) {
				LOG.error("超级少儿鉴权异常 用户："+userID+","+e.getMessage());
				return "0";
			}
		}else if("mv".equals(type)){
			String movResult = "504";
			String tvResult = "504";
			try {
				for(String s : vipService){
					String mtvResult = serviceAuth(userID, s,request, response);
					if("0".equals(mtvResult)) {
						LOG.debug("鉴权结果已订购超清影院包 用户："+userID);
						return mtvResult;
					}
				}
			}catch(Exception e) {
				LOG.error("超清影院服务鉴权异常："+e.getMessage());
				return "0";
			}

			try {
				//电影服务鉴权
				for(String s : movService){
					movResult = serviceAuth(userID, s, request, response);
					if("0".equals(movResult)) {
						//LOG.debug("鉴权结果已订购电影包 用户："+userID);
						break;
					}
				}
				//电视剧服务鉴权
				for(String s : tvService){
					tvResult = serviceAuth(userID, s,request, response);
					if("0".equals(tvResult)) {
						//LOG.debug("鉴权结果已订购电视剧包 用户："+userID);
						break;
					}
				}
			}catch(Exception e) {
				LOG.error("电影电视剧服务鉴权异常："+e.getMessage());
				return "0";
			}

			try {
				//判断电影、电视剧是否都订购
				if("0".equals(movResult) && "0".equals(tvResult)){
					LOG.debug("鉴权结果已订购影视剧或者电视剧包和电影包 用户："+userID);
					return "0";
				}else if("504".equals(movResult) && "504".equals(tvResult)){
					LOG.debug("鉴权结果未订购电视剧包且未订购电影包 用户："+userID);
					return "504";
				}else if("0".equals(movResult) && "504".equals(tvResult)){
					//电影服务鉴权通过，电影包鉴权
					for (String s : mvProduct) {
						movResult = productIDAuth(userID, s, request, response);
						if ("0".equals(movResult)) {
							LOG.debug("鉴权结果未订购电视剧包但是订购电影包月 用户：" + userID);
							return "100";
						}
					}
				}else if("504".equals(movResult) && "0".equals(tvResult)){
					//电视剧服务鉴权通过，电视剧包鉴权
					for (String s : tvProduct) {
						tvResult = productIDAuth(userID, s, request, response);
						if ("0".equals(tvResult)) {
							LOG.debug("鉴权结果未订购电影包但是订购电视剧包月 用户：" + userID);
							return "200";
						}
					}
				}
			}catch(Exception e) {
				LOG.error("电影电视剧产品包鉴权异常："+e.getMessage());
				return "0";
			}
		}else if("xm".equals(type)) {
			try {
				return productIDAuth( userID, "100111", request, response);
			}catch(Exception e) {
				LOG.error("戏曲订购鉴权异常 用户："+userID);
				return "0";
			}
		}*/
		return "600";
	}

	/**
	 * 服务鉴权
	 */
	private String  serviceAuth(String userID,String serviceID,HttpServletRequest request,HttpServletResponse response) {
		int readTimeOut = 3000;
		int connectTimeout = 3000;
		AuthenticatedService authenticatedService = new AuthenticatedService(request,response);
		return authenticatedService.getAuthenticatedResult(userID,serviceID,readTimeOut,connectTimeout);
	}

	/**
	 * 产品包鉴权
	 */
	private String productIDAuth(String serverid, String productId, HttpServletRequest request, HttpServletResponse response) {
		LOG.debug("userID"+serverid+"productID="+productId);
		try {
			AuthenticatedVo authVo = new AuthenticatedVo();
			authVo.setProductCode(productId);
			authVo.setServerid(serverid);

			AuthenticatedService authenticatedService = new AuthenticatedService(request, response);
			return authenticatedService.getAuthenticatedResultByProductID(authVo);
		}catch(Exception e) {
			LOG.error("产品包鉴权异常："+e);
			return "0";
		}
	}

	/**
	 * 切割成数组
	 * @param str 字符串
	 * @return 返回数组
	 */
	private String[] splits(String str) {
		return str.split(",");
	}

	/**
	 * 接口取出时间 例：20181212121212  年月日时分秒
	 * 转换date yyyy-MM-dd HH:mm:ss
	 */
	private String dateChange(String str) {
		StringBuilder sb = new StringBuilder(str);
		sb.insert(4, "-");
		sb.insert(7,"-");
		sb.insert(10," ");
		sb.insert(13,":");
		sb.insert(16,":");
		str = sb.toString();
		return str;
	}

	/**
	 * 时间转换
	 */
	private Date datesubstr(String time) {
		try {
			SimpleDateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");
			if(time != null){
				return ymd.parse(time.substring(0, 10));
			}else{
				return null;
			}
		}catch(Exception e) {
			LOG.error("活动时间异常"+e);
			return null;
		}
	}
}